﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using UIWindow.Domains;
using UIWindow.Enums;
using UIWindow.Models;

namespace UIWindow.GlobalParameters
{
    [Attributes.Singleton]
    public class DeviceGlobal
    {
        public ObservableCollection<DeviceModel> DeviceList { get; set; }
        public DeviceGlobal()
        {
            if (!File.Exists(GlobalStart.DevicePath)) DeviceList = new ObservableCollection<DeviceModel>();
            else DeviceList = JsonSerializer.Deserialize<ObservableCollection<DeviceModel>>(File.ReadAllText(GlobalStart.DevicePath, Encoding.UTF8));
        }

        public void Save() => File.WriteAllText(GlobalStart.DevicePath, JsonSerializer.Serialize(DeviceList), Encoding.UTF8);

        /// <summary>
        /// 添加单设备
        /// </summary>
        /// <param name="index">索引</param>
        /// <param name="ipcom"></param>
        /// <param name="port"></param>
        /// <param name="baudRate"></param>
        /// <param name="isSocket"></param>
        /// <param name="type"></param>
        public void Add(string ipcom, int port, int baudRate, bool isSocket, DeviceType type)
        {
            DeviceList.Add(new DeviceModel()
            {
                Index = 1,
                IPofCom = ipcom,
                Port = port,
                BaudRate = baudRate,
                IsSocket = isSocket,
                Types = type
            });
            Save();
        }

        public void Delete(DeviceModel model)
        {
            DeviceList.Remove(model);
            Save();
        }

        /// <summary>
        /// 生成IP地址
        /// </summary>
        /// <param name="startAddress">开始地址</param>
        /// <param name="startPort">开始端口</param>
        /// <param name="endAddress">结束地址</param>
        /// <param name="endPort">结束端口</param>
        public void AddDevices(string startAddress, string startPort, string endAddress, string endPort, bool isSocket, DeviceType type)
        {
            string[] str = new string[] { startAddress, startPort, endAddress, endPort };
            GenerateAddress(str, type,
                GetAddressPortInt(str),
                DeviceList);
            Save();
        }

        #region 计算IP地址差与生成
        private void GenerateAddress(string[] str, DeviceType deviceType, CalculateWeighingAddress calculate, ObservableCollection<DeviceModel> servers)
        {
            if (string.IsNullOrEmpty(str[0]) || string.IsNullOrEmpty(str[1]) || string.IsNullOrEmpty(str[2]) || string.IsNullOrEmpty(str[3])) return;
            if (calculate.IPLength == 0)
            {
                for (int i = 0; i <= calculate.PortLength; i++)
                {
                    servers.Add(new DeviceModel()
                    {
                        IPofCom = calculate.Address,
                        Port = calculate.StartPort + i,
                        Types = deviceType,
                        IsSocket = true,
                        Index = i + 1,
                    });
                }
                return;
            }
            for (int i = 0; i <= calculate.IPLength; i++)
            {
                servers.Add(
                    new DeviceModel()
                    {
                        IPofCom = $"{calculate.StrArray[0]}.{calculate.StrArray[1]}.{calculate.StrArray[2]}.{calculate.StartIP + i}",
                        Port = calculate.StartPort,
                        Types = deviceType,
                        IsSocket = true,
                        Index = i + 1,
                    });
            }
        }

        private CalculateWeighingAddress GetAddressPortInt(string[] str)
        {
            string[] strArray = str[0].Split('.');
            var obj = new CalculateWeighingAddress()
            {
                Address = str[0],
                StrArray = strArray,
                StartIP = Convert.ToInt32(strArray[3]),
                StartPort = Convert.ToInt32(str[1]),
                EndIP = Convert.ToInt32(str[2].Split('.')[3]),
                EndPort = Convert.ToInt32(str[3])
            };
            obj.IPLength = obj.EndIP - obj.StartIP;
            obj.PortLength = obj.EndPort - obj.StartPort;
            return obj;
        }

        private class CalculateWeighingAddress
        {
            /// <summary>
            /// IP地址
            /// </summary>
            public string Address { get; set; }
            /// <summary>
            /// 开始地址最后一位
            /// </summary>
            public int StartIP { get; set; }
            /// <summary>
            /// 结束地址最后一位
            /// </summary>
            public int EndIP { get; set; }
            /// <summary>
            /// 开始端口号
            /// </summary>
            public int StartPort { get; set; }
            /// <summary>
            /// 结束端口号
            /// </summary>
            public int EndPort { get; set; }
            /// <summary>
            /// IP差
            /// </summary>
            public int IPLength { get; set; }
            /// <summary>
            /// 端口号差
            /// </summary>
            public int PortLength { get; set; }
            /// <summary>
            /// 分割IP地址后的数组
            /// </summary>
            public string[] StrArray { get; set; }
        }
        #endregion
    }
}
